import asyncio
import cv2
import sys
import subprocess
import time


async def test_camera(camera_id):
    """测试摄像头是否正常工作"""
    print(f"正在测试摄像头 ID: {camera_id}...")
    try:
        cap = cv2.VideoCapture(camera_id)
        if not cap.isOpened():
            print(f"✗ 无法打开摄像头 ID: {camera_id}")
            return False

        # 尝试读取几帧
        for i in range(5):
            ret, frame = cap.read()
            if not ret or frame is None:
                print(f"✗ 摄像头 ID: {camera_id} 无法读取帧")
                cap.release()
                return False
            print(f"✓ 摄像头 ID: {camera_id} 成功读取第 {i+1} 帧")

        cap.release()
        print(f"✓ 摄像头 ID: {camera_id} 测试通过")
        return True
    except Exception as e:
        print(f"✗ 摄像头 ID: {camera_id} 测试失败: {e}")
        return False


async def test_microphone():
    """测试麦克风是否可用。
    - 优先尝试 sounddevice，然后 pyaudio，最后 ffmpeg
    """
    # 抑制ALSA错误信息
    import os
    os.environ['ALSA_DEBUG'] = '0'
    
    try:
        # 方法1: 优先尝试 sounddevice (更稳定，错误更少)
        try:
            import sounddevice as sd  # type: ignore
            sd.rec(frames=int(48000*0.1), samplerate=48000, channels=1, dtype='int16')
            sd.wait()
            return True
        except Exception:
            pass
        
        # 方法2: 尝试 pyaudio (跨平台，更稳定)
        try:
            import pyaudio
            p = pyaudio.PyAudio()
            # 测试默认输入设备
            stream = p.open(format=pyaudio.paInt16, channels=1, rate=48000, 
                          input=True, frames_per_buffer=1024)
            stream.close()
            p.terminate()
            return True
        except Exception:
            pass
        
        # 方法3: Linux 下使用 ffmpeg
        if sys.platform == "linux":
            test_commands = [
                # ALSA 默认设备
                ["ffmpeg", "-loglevel", "quiet", "-f", "alsa", "-i", "default", "-t", "0.1", "-ac", "1", "-ar", "48000", "-f", "null", "-"],
                # PulseAudio 默认设备
                ["ffmpeg", "-loglevel", "quiet", "-f", "pulse", "-i", "default", "-t", "0.1", "-ac", "1", "-ar", "48000", "-f", "null", "-"],
                # ALSA 第一个设备
                ["ffmpeg", "-loglevel", "quiet", "-f", "alsa", "-i", "hw:0,0", "-t", "0.1", "-ac", "1", "-ar", "48000", "-f", "null", "-"],
            ]
            
            for cmd in test_commands:
                try:
                    proc = subprocess.run(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, timeout=3)
                    if proc.returncode == 0:
                        return True
                except (subprocess.TimeoutExpired, FileNotFoundError):
                    continue
        
        return False
    except Exception:
        return False


async def test_speaker():
    """测试扬声器是否可用。
    - 优先尝试 sounddevice，然后 pyaudio，最后 ffplay
    """
    # 抑制ALSA错误信息
    import os
    os.environ['ALSA_DEBUG'] = '0'
    
    try:
        # 方法1: 优先尝试 sounddevice (更稳定，错误更少)
        try:
            import numpy as np  # type: ignore
            import sounddevice as sd  # type: ignore
            sr = 48000
            t = np.linspace(0, 0.1, int(sr*0.1), endpoint=False)
            tone = (0.1*np.sin(2*np.pi*440*t)).astype(np.float32)
            sd.play(tone, sr)
            sd.wait()
            return True
        except Exception:
            pass
        
        # 方法2: 尝试 pyaudio (跨平台，更稳定)
        try:
            import pyaudio
            import numpy as np
            p = pyaudio.PyAudio()
            # 生成短测试音
            sr = 48000
            t = np.linspace(0, 0.1, int(sr*0.1), endpoint=False)
            tone = (0.1*np.sin(2*np.pi*440*t)).astype(np.float32)
            # 测试默认输出设备
            stream = p.open(format=pyaudio.paFloat32, channels=1, rate=sr, 
                          output=True, frames_per_buffer=1024)
            stream.write(tone.tobytes())
            stream.close()
            p.terminate()
            return True
        except Exception:
            pass
        
        # 方法3: Linux 下使用 ffplay
        if sys.platform == "linux":
            try:
                import numpy as np  # type: ignore
                from AudioPlaybackManager import AudioPlaybackManager
                player = AudioPlaybackManager(preferred_backend="ffplay")
                player.start(sample_rate=48000, channels=1)
                samples = np.zeros((int(48000*0.1), 1), dtype='int16')
                player.write(samples)
                time.sleep(0.15)
                player.stop()
                return True
            except Exception:
                return False
        
        return False
    except Exception:
        return False


